#include "arbitrage.h"
#include "showWidget.h"
#include <QDebug.h>

arbitrage::arbitrage(QWidget *parent)
    : QWidget(parent)
{
    this->num = 5;
    ui.setupUi(this);
    connect(ui.flush, &QPushButton::clicked, this,&arbitrage::reflush);
    connect(ui.add, &QPushButton::clicked, this, &arbitrage::addItem);
    connect(ui.deleteBtn, &QPushButton::clicked, this, &arbitrage::deleteItem);
    connect(ui.admit, &QPushButton::clicked, this, &arbitrage::admit);
    connect(ui.read, &QPushButton::clicked, this, &arbitrage::read);
    connect(ui.read_2, &QPushButton::clicked, this, &arbitrage::read_2);
    connect(ui.listWidget, &QListWidget::itemChanged, this, &arbitrage::makeSureNoSameItem);
    //窗口图标
    this->setWindowIcon(QIcon("窗口，表单.png"));
    this->setWindowTitle("套汇");
    //鼠标光标
    QPixmap pixmap = QPixmap("光标.png");
    pixmap = pixmap.scaled(20, 20, Qt::KeepAspectRatio);
    QCursor cursor = QCursor(pixmap);
    setCursor(cursor);
}

arbitrage::~arbitrage()
{

}

// 刷新数量 并且置空
void arbitrage::reflush() {
    // 更新 Num
    num = ui.Num->text().toUInt();
    // 重建列表
    ui.listWidget->clear();
    for (int i = 0; i < num; i++) {
        QListWidgetItem* item = new QListWidgetItem;
        item->setText(QString("新建项%1").arg(i+1));
        item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsEditable);
        ui.listWidget->addItem(item);
    }
    // 重建邻接矩阵
    ui.tableWidget->clearContents();
    ui.tableWidget->setColumnCount(num);
    ui.tableWidget->setRowCount(num);
    for (int i = 0; i < num; i++) {
        for (int j = 0; j < num; j++) {
                QTableWidgetItem* item = new QTableWidgetItem();  
                ui.tableWidget->setItem(i, j, item);  
                item->setTextAlignment(Qt::AlignCenter);
        }
    }
}
// 添加货币数量
void arbitrage::addItem() {
    // 增添货币数量
    QListWidgetItem* item = new QListWidgetItem;
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
    item->setText(QString("新建项%1").arg(ui.listWidget->count()+1));
    ui.listWidget->addItem(item);
    // 更新Num
    num = ui.listWidget->count();
    ui.Num->setText(QString::number(num));
    // 更新表格
    ui.tableWidget->setColumnCount(num);
    ui.tableWidget->setRowCount(num);
    // 为表格添加新的 Item
    for (int i = 0; i < num; i++) {
        for (int j = 0; j < num; j++) {
            if (ui.tableWidget->item(i, j) == nullptr) {
                QTableWidgetItem* item = new QTableWidgetItem();
                item->setTextAlignment(Qt::AlignCenter);
                ui.tableWidget->setItem(i, j, item);
            }
        }
    }
}
// 删除货币
void arbitrage::deleteItem() {
    int rowNum;
    if (!ui.listWidget->currentItem()) {
        QMessageBox selectWarning(QMessageBox::Icon::Warning, "警告", "<font size='24' color='red'>请先选中一项再进行删除");
        selectWarning.setWindowIcon(QIcon("警告.png"));
        selectWarning.exec();
        return;
    }
    else {
        rowNum = ui.listWidget->currentRow();
        QListWidgetItem* item = ui.listWidget->takeItem(rowNum);
        delete item;
    }
    // 更新Num
    num = ui.listWidget->count();
    ui.Num->setText(QString::number(num));
    // 更新邻接矩阵
    for (int i = rowNum; i < num; i++) {
        for (int j = rowNum; j < num; j++) {
            QTableWidgetItem* item = ui.tableWidget->item(i + 1, j + 1);
            ui.tableWidget->item(i, j)->setText(item->text());
        }
    }
    for (int i = rowNum; i < num; i++) {
        for (int j = 0; j < rowNum ; j++) {
            QTableWidgetItem* item = ui.tableWidget->item(i + 1, j);
            ui.tableWidget->item(i, j)->setText(item->text());
        }
    }
    for (int j = rowNum; j < num; j++) {
        for (int i = 0; i < rowNum ; i++) {
            QTableWidgetItem* item = ui.tableWidget->item(i, j+1);
            ui.tableWidget->item(i, j)->setText(item->text());
        }
    }
    ui.tableWidget->setColumnCount(num);
    ui.tableWidget->setRowCount(num);
}
// 确保货币未重复
void arbitrage::makeSureNoSameItem() {
    QString str;
    for (int i = 0; i < num; i++) {
        if (i != ui.listWidget->currentRow()) {
            if(ui.listWidget->item(i)!=nullptr)
                str = ui.listWidget->item(i)->text();
            if (ui.listWidget->currentItem()!=nullptr && str == ui.listWidget->currentItem()->text()) {
                // 重新输入名字
                QInputDialog resetStr(this, Qt::WindowType::Widget);
                QString newName = resetStr.getText(this, "重置", "货币名称不可重复\n请重新输入货币名称：");;
                ui.listWidget->currentItem()->setText(newName);
            }
        }

    }
}
// 提交  界面→数据
void arbitrage::admit() {
    QStringList NameStrList;
    // 获取货币列表   界面→数据
    for (int i = 0; i < num; i++) {
        QListWidgetItem* item = ui.listWidget->item(i);
        if (NameStrList.contains(item->text())) {
            QMessageBox sameWarning(QMessageBox::Icon::Critical, "警告", "<font size='24' color='red'>货币名称不可重复");
            sameWarning.setWindowIcon(QIcon("警告.png"));
            sameWarning.exec();
            return ;
        }
        else {
            NameStrList.append(item->text());
        }
        currency[i] = item->text();
    }
    // 获取邻接矩阵   界面→数据
    for (int i = 0; i < num; i++) {
        for (int j = 0; j < num; j++) {
            QTableWidgetItem* item = ui.tableWidget->item(i, j);
            // 注意检查是否为空
            if (item != nullptr && !item->text().isEmpty()) {
                arr[i][j] = item->text().toDouble();
            }
            else {
                arr[i][j] = 0;
            }
        }
    }
    // 创建第二个窗口对象    并传导数值
    showWidget* page = new showWidget();     
    page->m.setVexNum(this->num);
    page->m.setVex(this->currency);
    page->m.setEdge(this->arr);

    //for (int i = 0; i < 5; i++) {
    //    for (int j = 0; j < 5; j++) {
    //        qDebug() << page->m.edge[i][j];
    //    }
    //}
    // qDebug() << page->m.getVexNum();
    
    // 
    Result result;
    // 此处 flag 可以删除
    bool flag = false;
    int index = 0;
    for (int start = 0;start < page->m.getVexNum();start++) {
        QVector<bool> visited(page->m.getVexNum(), false);
        QVector<int> path;
        page->dfs(visited, path, start, start, 1.0, result, index, flag);
    }
    // 统计数据
    double max = 1, sum = 0;
    for (int i = 0; i < index; i++) {
        double temp = page->ui.Table->item(i, 1)->text().toDouble();
        if ( temp > max) {
            max = temp;
        }
        sum += temp;
    }
    // 界面输出显示
    page->ui.accountingTable->setItem(0, 0, new QTableWidgetItem(QString::number(index)));
    page->ui.accountingTable->setItem(0, 1, new QTableWidgetItem(QString::number(sum/index)));
    page->ui.accountingTable->setItem(0, 2, new QTableWidgetItem(QString::number(max)));
    page->ui.accountingTable->item(0, 0)->setTextAlignment(Qt::AlignCenter);
    page->ui.accountingTable->item(0, 1)->setTextAlignment(Qt::AlignCenter);
    page->ui.accountingTable->item(0, 2)->setTextAlignment(Qt::AlignCenter);
    // 切换界面操作
    this->close();                           
    page->show();                           
}
// 读文件 判断合法行
bool isValidCurrencyLine(const string& line) {
    istringstream iss(line);
    string currency1, currency2;
    double rate;
    if (iss >> currency1 >> currency2 >> rate &&
        currency1.length() == 3 && all_of(currency1.begin(), currency1.end(), ::isalpha) &&
        currency2.length() == 3 && all_of(currency2.begin(), currency2.end(), ::isalpha) &&
        rate > 0) { // 添加rate > 0 检查，确保汇率为正数
        return true;
    }
    return false;
}
// 读文件
void readfile(string address, double arr[][25], QString currency[]) {
    set<string> currencies;
    ifstream fp;
    string line;
    fp.open(address, ios::in);
    if (!fp.is_open()) {
        QMessageBox fileOpenError = QMessageBox(QMessageBox::Warning, "文件打开异常", "OPEN FILE ERROR");
    }
    while (getline(fp, line)) {
        istringstream iss(line);
        string token;
        while (iss >> token) {
            // 假设国家代码是3个字母长
            if (token.length() == 3 && all_of(token.begin(), token.end(), ::isalpha)) {
                currencies.insert(token);
            }
        }
    }
    fp.close();           //到此只读取国家代码

    int i = 0;
    map<string, int> mp;
    for (const auto& cur : currencies) {
        currency[i] = QString::fromStdString(cur);
        mp[cur] = i;
        i++;                                    //此处将国家代码与索引数字绑定
    }

    string a, b;
    double val;
    fp.open(address, ios::in);
    if (!fp.is_open()) {
        QMessageBox fileOpenError = QMessageBox(QMessageBox::Warning, "文件打开异常", "OPEN FILE ERROR");
    }
    while (getline(fp, line)) {
        if (isValidCurrencyLine(line)) {
            istringstream iss(line);
            iss >> a >> b >> val;
            map<string, int>::iterator itA = mp.find(a);
            map<string, int>::iterator itB = mp.find(b);
           // qDebug() << itA->second << " " << itB->second<<" "<<val;
            arr[itA->second][itB->second] = val;
        }
    }

}
// 更新    数据→界面
void arbitrage::update() {
    // 清空列表
    ui.listWidget->clear();
    // 数据→界面
    for (int i = 0; i < 25; i++) {
        if (!currency[i].isEmpty()) {
            ui.listWidget->addItem(new QListWidgetItem());
            ui.listWidget->item(i)->setText(this->currency[i]);
        }
        else {
            // 跳出循环前 更新Num
            this->num = i;
            ui.Num->setText(QString::number(i));
            break;
        }
    }
    // 更新邻接矩阵    数据→界面
    ui.tableWidget->setRowCount(num);
    ui.tableWidget->setColumnCount(num);
    // 确保 对角线为1
    for (int i = 0; i < this->num; i++) {
        this->arr[i][i] = 1;
    }
    // 数据→界面
    for (int i = 0; i < this->num; i++) {
        for (int j = 0; j < this->num; j++) {
            QTableWidgetItem *item = ui.tableWidget->item(i, j);
            if (item != nullptr) {
                ui.tableWidget->item(i, j)->setText(QString::number(arr[i][j]));
            }
            else {
                item = new QTableWidgetItem(QString::number(arr[i][j]));
                item->setTextAlignment(Qt::AlignCenter);
                ui.tableWidget->setItem(i, j, item);
            }
            
        }
    }
}
// 读取文件
void arbitrage::read() {
    // 选取文件
    QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", "Text Files(*.txt)");
    if (!fileName.isEmpty()&&fileName.compare("")!=0){
        readfile(fileName.toStdString(), this->arr, this->currency);
        update();
    }
}
// 读取默认文件
void arbitrage::read_2() {
    QProcess program;
    QString cmd = "writeFile.exe";
    program.start(cmd);
    program.waitForFinished();
    QString fileName = "toread.txt";
    readfile(fileName.toStdString(), this->arr, this->currency);
    update();
}